AWS CloudFormationで管理しているAmazon RDS for MySQLからAmazon Aurora MySQLに移行する手順を整理した
こんにちは。サービスグループの武田です。
Amazon RDS for MySQLデータベースからAmazon Aurora MySQLへの移行パスはいくつか用意されています。それではAWS CloudFormation(以下、CFn)で管理をしている場合はどうでしょうか。このエントリではその手順を整理してみました。
Aurora移行時に検討すべき事項
Auroraは非常に堅牢な、AWSのマネージドRDBサービスです。MySQL互換およびPostgreSQL互換のAuroraが提供されていますが、今回はMySQL互換を対象としています。
MySQL互換 ということで、アプリケーションやツールは差異を意識せずに使用できますが、MySQLのすべての機能を備えているわけではありません。例を挙げると、MyISAMストレージエンジンなど特定の機能が使えないことや、指定できないパラメーターが存在したりします。これらはドキュメントに記載されているため、しっかりと確認しましょう。もちろん、実際にAuroraを構築してアプリケーションを稼働させてみることも重要です。
移行手順の整理
さてデータベースの移行ですが、次の2ステップに分けて整理するのがよさそうです。
- RDSからAuroraへのデータコピー
- AuroraクラスターとCFnテンプレートの同期
データコピーについては次の方法が考えられます。
- スナップショット作成/リストア
- リードレプリカ作成
スナップショットを利用した移行はリストアが完了するまで停止点が必要です。一方でリードレプリカを使用する方法はスナップショットに比べてシステムの停止時間を小さくできます。
次にAuroraクラスターとCFnテンプレートの辻褄を合わせることを考えます。これも次の方法が考えられます。
- リストアするスナップショットをCFnテンプレートで指定する
- 構築したAuroraクラスターをCFnスタックにインポートする
以上のことを整理すると、移行パスは次のものが考えられます。
- 既存のDBからスナップショットを作成し、それを
SnapshotIdentifier
に指定した新しいAuroraクラスターをCFnで作成する - 既存のDBからスナップショットを作成しリストアしてAuroraクラスターを構築。それをCFnスタックにインポートする
- 既存のDBのリードレプリカをAuroraで作成し、それをCFnスタックにインポートする
CFnのインポート機能がなかった時代はおそらく1しか方法がなかったのではないかと想像します。将来はどうなるか分かりませんが、今なら3の方法が簡単そうです。というわけで、前置きが長くなりましたが、整理した3の方法を実際にやってみました。
手順は次のとおりです。
- CFnでDBインスタンスを構築
- リードレプリカをAuroraクラスターで作成(手作業)
- リードレプリカを昇格(手作業)
- AuroraクラスターをCFnスタックにインポート(手作業)
- CFnを更新してDBインスタンスを削除
移行元となるDBインスタンスの作成
まずはシンプルな構成のDBインスタンスを1台構築します。これが移行元となるデータベースになります。次のCFnテンプレートから始めましょう。SubnetGroupのSubnetIds
やDBDNSRecordのHostedZoneId
などは実際の環境に合わせて修正してください。
Resources: DBInstance: Type: AWS::RDS::DBInstance DeletionPolicy: Snapshot Properties: AllocatedStorage: '5' DBInstanceClass: db.t3.medium DBParameterGroupName: !Ref DBParameterGroup DBSubnetGroupName: !Ref DBSubnetGroup Engine: MySQL EngineVersion: 5.7.30 MasterUsername: admin MasterUserPassword: your_secret StorageType: gp2 DBSubnetGroup: Type: AWS::RDS::DBSubnetGroup Properties: DBSubnetGroupDescription: custom subnet group SubnetIds: - subnet-aaaaaaa - subnet-bbbbbbb - subnet-ccccccc DBParameterGroup: Type: AWS::RDS::DBParameterGroup Properties: Description: custom paramter group Family: MySQL5.7 Parameters: character_set_database: utf8mb4 character_set_client: utf8mb4 character_set_connection: utf8mb4 character_set_results: utf8mb4 character_set_server: utf8mb4 DBDNSRecord: Type: AWS::Route53::RecordSet Properties: HostedZoneId: ABCDEFGHIJKLMN Name: db.example.com Type: CNAME TTL: 60 ResourceRecords: - !GetAtt DBInstance.Endpoint.Address
DBインスタンスおよび参照用に、Route 53にCNAMEレコードを追加しています。このように名前を与えておくことで、Auroraに切り替えてもアプリケーションからは同じ名前でDBにアクセスできます。テンプレートが用意できたらスタックを作成します。
$ aws cloudformation create-stack --template-body file://rds.template.yml --stack-name rds-update-test
しばらく待っているとDBインスタンスなどが作成されます。
Route 53のレコードも作成されています。
Auroraでリードレプリカを作成
DBインスタンスが用意できたので、次はAuroraクラスターを構築します。今回は先ほど構築したDBインスタンスのリードレプリカとして構成することで、自動的にデータが同期されるようにします。またクラスターを昇格するまでは自動的にレプリケーションされるため、任意のタイミングで構築できます。切り替えは計画メンテナンスの時間で行うが、リードレプリカの作成は事前に作成といったことが可能です。
リードレプリカの作成はマネジメントコンソールから簡単に行えます。作成されたDBインスタンスの詳細画面から、[アクション] > [Aurora リードレプリカの作成]を選択します。
リードレプリカの仕様を選択します(デフォルト部分は省略します)。
エンジンのバージョンはとりあえず現時点での最新を選びました。インスタンスクラスは先ほど作成したDBインスタンスに合わせました。
識別子を入力します。今回はmydbinstance
としました。
VPCなどはデフォルトとしていますが、サブネットグループは先ほどCFnで作成したものを選択しています。この辺は実際の環境に合わせましょう。
必要事項を選択できたらリードレプリカを作成します。待つこと30分程度でリードレプリカが作成されました。
RDSからAuroraへの移行作業
それでは準備が整いましたので、実際にAuroraへ切り替える移行作業をしていきましょう。
まずはAuroraクラスターがリードレプリカとして構成されているため、スタンドアローンに昇格させます。この作業以降、DBの同期は切れますので注意しましょう。Auroraクラスターを選択し、[アクション] > [昇格]を選択します。昇格自体は数分で完了します。
DBインスタンスのロールが マスター から インスタンス に変わればOKです。
続いてAuroraクラスターをCFnスタックにインポートします。マネジメントコンソールでCFnのスタックのページを開き、[スタックアクション] > [スタックへのリソースのインポート]を選択します。
インポートするためのテンプレートをアップロードします。
先ほど作成したCFnテンプレートにAuroraクラスターを追加したテンプレートを用意します。ポイントは「インポートだけ」をすることです。クラスターのパラメーターグループ追加や、DNSレコードの更新は次のステップで行います。
@@ -13,6 +13,35 @@ MasterUserPassword: your_secret StorageType: gp2 + DBCluster: + Type: AWS::RDS::DBCluster + DeletionPolicy: Retain + Properties: + DBClusterParameterGroupName: default.aurora-mysql5.7 + DBSubnetGroupName: !Ref DBSubnetGroup + Engine: aurora-mysql + EngineVersion: 5.7.mysql_aurora.2.08.1 + MasterUsername: admin + MasterUserPassword: your_secret + + DBWriterInstance: + Type: AWS::RDS::DBInstance + DeletionPolicy: Retain + Properties: + DBClusterIdentifier: !Ref DBCluster + DBInstanceClass: db.t3.medium + DBSubnetGroupName: !Ref DBSubnetGroup + Engine: aurora-mysql + + DBReaderInstance: + Type: AWS::RDS::DBInstance + DeletionPolicy: Retain + Properties: + DBClusterIdentifier: !Ref DBCluster + DBInstanceClass: db.t3.medium + DBSubnetGroupName: !Ref DBSubnetGroup + Engine: aurora-mysql + DBSubnetGroup: Type: AWS::RDS::DBSubnetGroup Properties:
このテンプレートをアップロードして進めると、インポートするリソースを指定する画面となります。実際のAuroraクラスターの名前を確認しながら「識別子の値」をそれぞれ埋めます。
問題なければ「変更」としてリソースが認識されます。[リソースをインポート]ボタンをポチッと押しましょう。
無事にスタックに取り込まれたようです。
最後の仕上げとして最終形のCFnテンプレートを用意し、スタックを更新しましょう。
@@ -1,23 +1,9 @@ Resources: - DBInstance: - Type: AWS::RDS::DBInstance - DeletionPolicy: Snapshot - Properties: - AllocatedStorage: '5' - DBInstanceClass: db.t3.medium - DBParameterGroupName: !Ref DBParameterGroup - DBSubnetGroupName: !Ref DBSubnetGroup - Engine: MySQL - EngineVersion: 5.7.30 - MasterUsername: admin - MasterUserPassword: your_secret - StorageType: gp2 - DBCluster: Type: AWS::RDS::DBCluster DeletionPolicy: Retain Properties: - DBClusterParameterGroupName: default.aurora-mysql5.7 + DBClusterParameterGroupName: !Ref AuroraClusterParameterGroup DBSubnetGroupName: !Ref DBSubnetGroup Engine: aurora-mysql EngineVersion: 5.7.mysql_aurora.2.08.1 @@ -51,11 +37,11 @@ - subnet-8b9b60c2 - subnet-52d9877a - DBParameterGroup: - Type: AWS::RDS::DBParameterGroup + AuroraClusterParameterGroup: + Type: AWS::RDS::DBClusterParameterGroup Properties: - Description: custom paramter group - Family: MySQL5.7 + Description: custom cluster paramter group + Family: aurora-mysql5.7 Parameters: character_set_database: utf8mb4 character_set_client: utf8mb4 @@ -71,4 +57,14 @@ Type: CNAME TTL: 60 ResourceRecords: - - !GetAtt DBInstance.Endpoint.Address + - !GetAtt DBCluster.Endpoint.Address + + DBReadDNSRecord: + Type: AWS::Route53::RecordSet + Properties: + HostedZoneId: ABCDEFGHIJKLMN + Name: db-ro.example.com + Type: CNAME + TTL: 60 + ResourceRecords: + - !GetAtt DBCluster.ReadEndpoint.Address
やっていることは次のことです。
- DBインスタンスおよびカスタムパラメーターグループの削除
- Auroraクラスター用のカスタムパラメーターグループ作成およびクラスターへの適用
db.example.com
のレコードを修正db-ro.example.com
のレコードを追加
それではスタックを更新します。
$ aws cloudformation deploy --template-file rds.template.yml --stack-name rds-update-test
しばらく待つとDBインスタンスの削除なども含めスタックの更新が完了します。Route 53の画面を確認してみると、レコードも更新されています。
まとめ
マネジメントコンソールやCLIを使うことで簡単にRDSの移行も行えます。ところがCFnが絡むと考えることが多くなって難易度が上がるように思えます。とはいえ、実際に検証してみることで手順も確認できますので、皆さんも気になることはどんどん試してみてください。